/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package sat;

import java.lang.String;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Vector;
import sat.convenience.Solution;

/**
 * Klasa zawrierająca metody pomocnicze dla algorytmu GSAT
 * @author bawey
 */
public class GsatToolkit {
    /**
     * Zwraca Vector rozwiązań stanowiących sąsiedztwo zadanego rozwiązania
     * @param solution rozwiązanie wyjściowe
     * @param distance dystans Hamminga
     * @return Vector podstawień
     */
    public static Vector<Solution>getNeighborhood(Solution solution, int distance){
        Vector<Solution> result = new Vector<Solution>();
        if(distance!=1){
            throw new UnsupportedOperationException();
        }else{
            result.ensureCapacity(solution.keySet().size());
            int i=0;
            for(Iterator it=solution.keySet().iterator(); it.hasNext(); ++i){
                result.add((Solution)solution.clone());
                String key = (String)it.next();
                result.get(i).put(key, (solution.get(key).booleanValue()?Boolean.FALSE:Boolean.TRUE));
          //      System.out.println(i);
          //      System.out.println(result.get(i));
            }
        }
        //System.out.println(result);
        return result;
    }
    
    /**
     * Inicjalizacja rozwiązania wartościami losowymi
     * @param solution
     * @return 
     */
    public static Solution randomize(Solution solution){
        Solution result = new Solution(); 
        for(Iterator i = solution.keySet().iterator(); i.hasNext(); ){
            String key = (String) i.next();
            result.put(key, (Math.random()>0.5?Boolean.TRUE:Boolean.FALSE));
        }
        return result;
    }
    
    /**
     * Zwraca najlepsze rozwiązanie znalezione w otoczeniu rozwiązania candidate.
     * Jeśli zwraca null - algorytm utknął
     * @param formula formuła logiczna
     * @param candidate wyjściowe podstawienia
     * @param area zbiór rozwiązań przeszukiwanych celem znalezienia lepszego
     * @return najlepsze z rozpatrywanych rozwiązań
     */
    public static Solution getBest(FormulaCNF formula, Solution candidate, Vector<Solution> area){
        //System.out.println(candidate);
        //System.out.println(area);
        float initialScore = formula.getTrueClausesPercentage(candidate);
        //System.out.println("initial score: "+initialScore);
        float bestScore = Float.NEGATIVE_INFINITY;
        int leader = -1;
        for(int i=0; i<area.size(); ++i){
            float score = formula.getTrueClausesPercentage(area.get(i))-initialScore;
            if(score>=bestScore){
                bestScore=score;
                leader=i;
            }
        }
        //System.out.println("best score: "+bestScore);
        return bestScore>=0f?area.get(leader):null;
    }

}
